package ru.compft.common.dao.impl;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import ru.compft.common.dao.SettingDao;
import ru.compft.common.data.Setting;
import ru.compft.common.data.meta.SettingProperty;

import javax.annotation.Resource;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: VVasiliev
 * Date: 24.09.12
 * Time: 13:44
 * DAO работы с настройками системы
 */
@Repository
public class SettingDaoImpl implements SettingDao {
    private static final Logger logger = LoggerFactory.getLogger(SettingDaoImpl.class);

    @Resource(name = "sessionFactory")
    private SessionFactory sessionFactory;


    @Override
    public List<Setting> getAllSettings() {
        Session session = null;
        try {
            session = sessionFactory.openSession();
            Criteria criteria = session.createCriteria(Setting.class);

            return criteria.list();
        } catch (HibernateException e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (session != null && session.isOpen()) session.close();
        }
        return null;
    }

    @Override
    public List<Setting> getSettings(int from, int count) {
        Session session = null;
        try {
            session = sessionFactory.openSession();
            Criteria criteria = session.createCriteria(Setting.class)
                    .setFirstResult(from)
                    .setMaxResults(count);

            return criteria.list();
        } catch (HibernateException e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (session != null && session.isOpen()) session.close();
        }
        return null;
    }

    @Override
    public int countAllSettings() {
        Session session = null;
        try {
            session = sessionFactory.openSession();
            Criteria criteria = session.createCriteria(Setting.class)
                    .setProjection(Projections.rowCount());

            final Object result = criteria.uniqueResult();
            return result != null ? Integer.parseInt(result.toString()) : 0;
        } catch (HibernateException e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (session != null && session.isOpen()) session.close();
        }
        return 0;
    }

    @Override
    public Setting getSettingById(Long id) {
        Session session = null;
        try {
            session = sessionFactory.openSession();
            return (Setting) session.get(Setting.class, id);
        } catch (HibernateException e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (session != null && session.isOpen()) session.close();
        }
        return null;
    }

    @Override
    public Setting getSettingByCode(String code) {
        Session session = null;
        try {
            session = sessionFactory.openSession();
            Criteria criteria = session.createCriteria(Setting.class)
                    .add(Restrictions.like(SettingProperty.code, code));

            return (Setting) criteria.uniqueResult();
        } catch (HibernateException e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (session != null && session.isOpen()) session.close();
        }
        return null;
    }

    @Override
    public Setting update(Setting setting) {
        Session session = null;
        Setting result = setting;
        try {
            session = sessionFactory.openSession();
//            Transaction transaction = session.beginTransaction();
            result = (Setting) session.merge(setting);
//            transaction.commit();
        } catch (HibernateException e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (session != null && session.isOpen()) session.close();
        }
        return result;
    }
}
